package no.ntnu.idi.deid.preprocessor.wordcount;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;

import no.ntnu.idi.deid.documentunits.Document;

public abstract class CountManager {
	
	protected TreeMap<String, Integer> map = new TreeMap<String, Integer>();
	protected ArrayList<Entity> sortedWords = new ArrayList<Entity>();;
	protected ArrayList<Entity> caseInsensitiveWords;
		
	
	public CountManager(List<Map<String, Integer>> inputMaps) {
		preProcessorCount(inputMaps);
		sort(map,sortedWords);
	}
		
	// This constructor is used to count for each document
	public CountManager(Document d) {
		documentCount(d);
		sort(map,sortedWords);
	}
	
	public void generateStatsDocument(String path) {
		Writer writer = null;
		try {
		writer = new BufferedWriter(new OutputStreamWriter(
				new FileOutputStream(path), "utf-8"));	
		for(int i = 0; i < sortedWords.size(); i++) {
			writer.write(sortedWords.get(i).toString()+"\n");	
		}
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
				try {
					writer.close();
				} catch (Exception e2) {
					e2.printStackTrace();
				}
		}
	}
//	
//	public List<Entity> getCaseInsensitiveWords() {
//		if(caseInsensitiveWords == null) {
//			caseInsensitiveWords = new ArrayList<Entity>();
//			generateCaseInsensitiveList();
//		}
//		return caseInsensitiveWords;
//	}

	public List<Entity> getSortedWords() {
		return sortedWords;
	}
	
	public void preProcessorCount(List<Map<String, Integer>> inputMaps) {
		for (Map<String, Integer> imap : inputMaps) {
			Iterator<Entry<String, Integer>> it = imap.entrySet().iterator();
			while (it.hasNext()) {
				Entry<String, Integer> pair =  it.next();
				if (map.containsKey(pair.getKey())) {
					map.put(pair.getKey().toString(),
							map.get(pair.getKey().toString())
									+ (Integer) pair.getValue());
				} else {
					map.put(pair.getKey().toString(), (Integer) pair.getValue());
				}
			}
		}
	}

	public Map<String, Integer> getMap() {
	return map;
}
	
	protected void insert(String s) {
		s = s.toLowerCase();
		if (map.containsKey(s)) {
			map.put(s, map.get(s) + 1);
		} else {
			map.put(s, 1);
		}
	}
		
	protected void sort(TreeMap<String, Integer> map, ArrayList<Entity> sortedList) {
		Iterator<Entry<String, Integer>> it = map.entrySet().iterator();
		while (it.hasNext()) {
			Entry<String, Integer> pair = it.next();
			Entity w = new Entity(pair.getKey().toString(),
					(Integer) pair.getValue());
			sortedList.add(w);
		}
		Collections.sort(sortedList);
	}
	
	protected abstract void documentCount(Document d);
	
}
